package com.neulogistics.contrib.procuredcenter.api.application.aop;

import com.neulogistics.contrib.procuredcenter.api.application.integrationevent.IProcuredCenterIntegrationEventService;

import com.neulogistics.contrib.procuredcenter.api.service.ThreadLocalService;
import com.neulogistics.infrastructure.cache.idservice.RedisIdUtil;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Aspect
@Component
public class TransactionalAspect {
    @Resource
    private IProcuredCenterIntegrationEventService procuredCenterIntegrationEventService;

    @Resource
    private RedisIdUtil redisIdUtil;


    @Value("${spring.application.name}")
    private String appName;

    private final String Transaction_Id_Key;

    public TransactionalAspect(@Value("${spring.application.name}") String appName) {
        Transaction_Id_Key = appName + ":" + "transactionId";
    }

    // 定义切点，匹配handler包下的所有类的带有 @Transactional 注解的handle方法
    @Pointcut("@annotation(com.neulogistics.infrastructure.common.annotation.ProduceEvent)")
    public void transactionalMethods() {}


    @Before("transactionalMethods()")
    public void beforeTransactional() {
        // 在带有 @Transactional 注解的方法执行前执行增强逻辑
        // 利用redis，生成全局唯一事务id
        long transactionId = redisIdUtil.nextId(Transaction_Id_Key);
        // 存入ThreadLocal
        ThreadLocalService.transactionId.set(transactionId);
    }

    @After("transactionalMethods()")
    public void afterTransactional() {
        // 在事务提交后的逻辑处理代码
        // 进行集成事件的集中发布
        long transactionId = ThreadLocalService.transactionId.get();
        procuredCenterIntegrationEventService.publishEvents(transactionId);
        // 移除transactionId
        ThreadLocalService.transactionId.remove();
    }
}
